package com.nineclock.approve.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.nineclock.approve.pojo.ApproveDefinition;
import com.nineclock.approve.resolver.ProcessNodeResolver;
import com.nineclock.approve.resolver.ProcessNodeResolverFactory;
import com.nineclock.approve.service.ActivitiService;
import lombok.extern.slf4j.Slf4j;
import org.activiti.bpmn.BpmnAutoLayout;
import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.bpmn.model.Process;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
@Slf4j
public class ActivitiServiceImpl implements ActivitiService {

    @Autowired
    private RepositoryService repositoryService;

    @Override
    public void deployProcessToActiviti(ApproveDefinition definition) {
//        动态构建Bpmnmodel
        BpmnModel model=new BpmnModel();

//        创建process
        Process process=new Process();
        process.setId("process_"+definition.getId());
        process.setName(definition.getName());

//       创建流程节点(开始节点, 审批节点, 网关节点 , 抄送节点,  结束节点)
        JSONArray jsonArray = JSONUtil.parseArray(definition.getFlowJson());
        addNodesToProcess(process,jsonArray);

        model.addProcess(process);
//      自动布局
        new BpmnAutoLayout(model).execute();

//        部署构建的审批流程BpmnModel到Activiti
        repositoryService.createDeployment()
                .name(definition.getName())
                .addBpmnModel(definition.getName()+".bpmn",model)
                .deploy();

        BpmnXMLConverter bpmnXMLConverter=new BpmnXMLConverter();
        byte[] bytes = bpmnXMLConverter.convertToXML(model);

        log.info("-------> 转换BpmnModel为XML数据 .");
        System.out.println(new String(bytes));
        log.info("-------> XML文件转换并输出完毕 . ");
    }

    private void addNodesToProcess(Process process, JSONArray jsonArray) {
        for (int i = 0; i < jsonArray.size(); i++) {
            JSONObject currNode = (JSONObject)jsonArray.get(i);
            JSONObject nextNode=null;

            if (i<jsonArray.size()-1){
                nextNode= (JSONObject) jsonArray.get(i+1);
            }

            //传递当前节点 , 下一个节点, 进行流程绘制 ------> 不同的节点类型调用的API不同, 绘制的方式不同 , 需要根据type来决定
            ProcessNodeResolver instance = ProcessNodeResolverFactory.getInstance(currNode.getStr("type"));
            instance.addFlowNodeToActiviti(process,currNode,nextNode);
        }
    }

    @Override
    public void dropProcessFromActiviti(ApproveDefinition definition) {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("process_" + definition.getId()).singleResult();
        repositoryService.deleteDeployment(processDefinition.getDeploymentId());

    }
}
